package com.tarena.lbs.business.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.attach.pojo.param.PicUpdateParam;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.business.constant.BusinessTypes;
import com.tarena.lbs.business.dao.repository.BusinessRepository;
import com.tarena.lbs.business.dao.repository.StoreRepository;
import com.tarena.lbs.business.pojo.param.StoreParam;
import com.tarena.lbs.business.pojo.param.UserLocationParam;
import com.tarena.lbs.business.pojo.po.BusinessPO;
import com.tarena.lbs.business.pojo.po.StorePO;
import com.tarena.lbs.business.pojo.po.StoreSearchPO;
import com.tarena.lbs.business.pojo.query.AreaStoreQuery;
import com.tarena.lbs.business.pojo.query.StoreQuery;
import com.tarena.lbs.business.pojo.vo.StoreVO;
import com.tarena.lbs.business.service.StoreService;
import com.tarena.lbs.common.enums.Roles;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StoreServiceImpl implements StoreService {

    @Autowired
    private StoreRepository storeRepository;

    @Autowired
    private BusinessRepository businessRepository;

//    @Autowired
//    private BasicOutPutSource outputSource;

    @DubboReference
    private AttachApi attachApi;

    @Override
    public PageResult<StoreVO> storeList(StoreQuery query){
        log.info("开始分页查询店铺列表，参数={}", query);

        PageInfo<StorePO> pageInfo = storeRepository.pageList(query);
        List<StoreVO> voList = convertToVoList(pageInfo.getList());

        PageResult<StoreVO> pageResult = new PageResult<>();
        pageResult.setTotal(pageInfo.getTotal());
        pageResult.setPageSize(pageInfo.getPageSize());

        return pageResult;
    }

    @Override
    public void save(StoreParam param) {
        try {
            UserPrinciple user = getCurrentUser();
            validateUserRole(user);

            BusinessPO business = getBusinessByUserId(user.getId());
            StorePO storePO = mapParamToStorePO(param, business);

            if (param.getId() == null || param.getId() <= 0) {
                storeRepository.add(storePO);
            } else {
                storePO.setId(param.getId());
                storeRepository.update(storePO);
            }

            bindPictures(param, storePO.getId());

        } catch (BusinessException e) {
            log.error("保存店铺信息失败", e);
            throw new RuntimeException("保存店铺信息失败", e);
        }
    }
    @Override
    public PageResult<StoreVO> getStoreByCity(AreaStoreQuery query) {
        log.info("根据城市区域查询店铺，参数={}", query);

        PageInfo<StorePO> pageInfo = storeRepository.getStoreByCity(query);
        List<StoreVO> voList = convertToVoList(pageInfo.getList());

        PageResult<StoreVO> pageResult = new PageResult<>();
        pageResult.setTotal(pageInfo.getTotal());
        pageResult.setPageSize(pageInfo.getPageSize());

        return pageResult;
    }

    @Override
    public void reported(UserLocationParam param) {
        try {
            UserPrinciple user = getCurrentUser();
            Integer userId = user.getId();

            Double latitude = Double.valueOf(param.getLatitude());
            Double longitude = Double.valueOf(param.getLongitude());

            List<StoreSearchPO> nearbyStores = storeRepository.getNearStore(latitude, longitude, 50D);

            if (CollectionUtils.isNotEmpty(nearbyStores)) {
                for (StoreSearchPO store : nearbyStores) {
                    sendLocationEvent(userId, store.getId());
                }
            }

        } catch (BusinessException e) {
            log.error("用户定位上报失败", e);
            throw new RuntimeException("用户定位上报失败", e); // 或者自定义处理
        }
    }




    private List<StoreVO> convertToVoList(List<StorePO> poList) {
        if (poList == null || poList.isEmpty()) return new ArrayList<>();

        return poList.stream()
                .map(po -> {
                    StoreVO vo = new StoreVO();
                    BeanUtils.copyProperties(vo, po);
                    return vo;
                })
                .collect(Collectors.toList());
    }

    private UserPrinciple getCurrentUser() throws BusinessException {
        UserPrinciple principle = AuthenticationContextUtils.get();
        if (principle == null) {
            throw new BusinessException("USER_NOT_LOGIN", "用户未登录");
        }
        return principle;
    }

    private void validateUserRole(UserPrinciple user) throws BusinessException {
        if (!Roles.SHOP.equals(user.getRole())) {
            throw new BusinessException("AUTH_NOT_EXISTS", "无权限访问");
        }
    }



    private BusinessPO getBusinessByUserId(Integer userId) throws BusinessException {
        BusinessPO business = businessRepository.busiStoreDetail(userId);
        if (business == null) {
            throw new BusinessException("BUSINESS_NOT_EXISTS", "商家不存在"); // 或 BUSINESS_NOT_EXISTS，看你的语义
        }
        return business;
    }

    private StorePO mapParamToStorePO(StoreParam param, BusinessPO business) {
        StorePO storePO = new StorePO();
        BeanUtils.copyProperties(storePO, param);
        storePO.setCreateTime(new Date());
        storePO.setUpdateTime(new Date());
        storePO.setBusinessId(business.getId());

        if (param.getStoreImagesIds() != null && !param.getStoreImagesIds().isEmpty()) {
            storePO.setStoreImagesId(String.join(",", param.getStoreImagesIds()));
        }

        return storePO;
    }

    private void bindPictures(StoreParam param, Integer storeId) throws BusinessException {
        List<PicUpdateParam> picParams = new ArrayList<>();

        if (param.getStoreLogo() != null && !param.getStoreLogo().isEmpty()) {
            PicUpdateParam logoParam = buildPicUpdateParam(storeId, param.getStoreLogo(), BusinessTypes.BIZ_LOGO);
            picParams.add(logoParam);
        }

        if (param.getStoreImagesIds() != null && !param.getStoreImagesIds().isEmpty()) {
            for (String imgId : param.getStoreImagesIds()) {
                PicUpdateParam imageParam = buildPicUpdateParam(storeId, imgId, BusinessTypes.BIZ_LICENSE);
                picParams.add(imageParam);
            }
        }

        if (!picParams.isEmpty()) {
            boolean success = attachApi.bathUpdateBusiness(picParams);
            Asserts.isTrue(!success, new BusinessException("BINDING_FAILURE", "图片绑定失败"));
        }
    }

    private PicUpdateParam buildPicUpdateParam(Integer storeId, String fileId, int businessType) {
        PicUpdateParam pic = new PicUpdateParam();
        pic.setBusinessId(storeId);
        pic.setBusinessType(businessType);
        pic.setId(Integer.valueOf(fileId));
        return pic;
    }

    private void sendLocationEvent(Integer userId, Integer storeId) {
//        LocationEvent event = new LocationEvent();
//        event.setUserId(userId);
//        event.setStoreId(storeId);
//
//        Message<LocationEvent> message = MessageBuilder.withPayload(event).build();
//        outputSource.getStoreLocationOutput().send(message);
    }
}
